package 高级并发编程学习_callable与Future的使用;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
//方式2：future+task
public class CallableAndFutureForMultiCompute1 {
    public static void main(String[] args) {  
    	System.out.println("主线程工作中1。。。");
        // 创建结果集合  
        List<Future<Integer>> futureList = new ArrayList<Future<Integer>>();  
        // 创建最大线程数为5的线程池  
        ExecutorService exec = Executors.newFixedThreadPool(5);
        //创建10个线程并提交到线程池，因为线程池中执行的线程内容一样，所以可以看到线程池是分10/5=2批次执行的
        for (int i = 0; i < 10; i++) {  
            //传入Callable对象创建ComputeTask,注意这里的task实现了callable接口  
        	ComputeTask task = new ComputeTask(i, ""+i);              
        	//future的泛型类型必须要与callable的泛型类型相一致  
            //提交给线程池执行任务：期货下单操作
            Future<Integer> future=exec.submit(task);  
            //期货订单集合
            futureList.add(future);  
        }  
        System.out.println("所有计算任务提交完毕, 主线程接着干其他事情！");       
        System.out.println("主线程工作中2。。。"); 
        System.out.println("主线程开始统计各计算线程计算结果  ");
        //主线程开始统计各计算线程计算结果  
        Integer totalResult = 0;  
        for (Future<Integer> ft : futureList) {  
            try {  
                //Future的get方法会自动阻塞,直到获取计算结果为止  
            	System.out.println("Future的get方法会自动阻塞,直到获取计算结果为止 ");
            	//因为子线程存在睡眠，这里发生阻塞，因为分两个批次，所以发生了两次阻塞：等待期货订单到期后提货
                totalResult = totalResult + ft.get();
                System.out.println("totalResult:"+totalResult);
            } catch (InterruptedException e) {  
                e.printStackTrace();  
            } catch (ExecutionException e) {  
                e.printStackTrace();  
            }  
        }  
        
        System.out.println("主线程统计各计算线程计算结果完成  ");
        System.out.println("主线程工作中3。。。"); 
		// 关闭线程池  
		/*当线程池调用该方法时,线程池的状态则立刻变成SHUTDOWN状态,以后不能再往线程池中添加任何任务，否则将会抛出RejectedExecutionException异常。
		 * 但是，此时线程池不会立刻退出，直到添加到线程池中的任务都已经处理完成，才会退出。
		 *  与它相似的还有一个shutdownNow()，它通过调用Thread.interrupt来实现线程的立即退出。*/
        exec.shutdown();  
        System.out.println("多任务计算后的总结果是:" + totalResult);  
  
    }  
}
